package cn.lili.modules.order.cart.render.util;

import cn.lili.common.utils.CurrencyUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 促销价格等比分配工具类
 *
 * @author paulG
 * @since 2020/8/21
 **/
@Slf4j
public class PromotionPriceUtil {

    private PromotionPriceUtil() {
        throw new IllegalStateException("Utility class");
    }

    /**
     * 将优惠金额按照比例分发到每个商品上
     *
     * @param skuPromotionDetail 参与活动的商品，以及商品总金额
     * @param discountPrice      需要分发的优惠金额
     */
    public static Map<String, Double> recountPrice(Map<String, Double> skuPromotionDetail, Double discountPrice) {
        //准备返回的消息，key为传递的skuId，value为分配到优惠金额
        Map<String, Double> result = new HashMap<>(skuPromotionDetail.size());

        //处理极端情况 如果优惠金额小于等于0，则不需要分配
        if (discountPrice <= 0) {
            skuPromotionDetail.forEach((k, v) -> result.put(k, 0D));
            return result;
        }


        // 获取map分配sku的总数，如果是最后一个商品分配金额，则将金额从百分比改为总金额扣减，避免出现小数除不尽
        int count = skuPromotionDetail.size();

        //已累加优惠金额
        Double deducted = 0D;


        //计算传入的所有金额汇总，用来计算单笔占比
        double totalPrice = 0D;
        for (Double value : skuPromotionDetail.values()) {
            totalPrice = CurrencyUtil.add(totalPrice, value);
        }

        //遍历map，分配优惠金额
        for (Map.Entry<String, Double> entry : skuPromotionDetail.entrySet()) {
            count--;
            //sku 优惠金额
            Double skuDiscountPrice;

            //非最后一个商品，则按照比例计算
            if (count > 0) {
                //商品金额占比 = 商品金额 / 总金额
                double point = CurrencyUtil.div(entry.getValue(), totalPrice, 4);
                //商品优惠金额 = 优惠金额 * 商品金额占比
                skuDiscountPrice = CurrencyUtil.mul(discountPrice, point);
                //累加已优惠金额 = 已优惠金额 + 商品优惠金额
                deducted = CurrencyUtil.add(deducted, skuDiscountPrice);

                result.put(entry.getKey(), skuDiscountPrice);
            }
            // 如果是最后一个商品 则减去之前优惠的金额来进行计算
            else {
                skuDiscountPrice = CurrencyUtil.sub(discountPrice, deducted);

                result.put(entry.getKey(), skuDiscountPrice);
            }
        }

        return result;

    }

}